/**
 * 方法装饰器
 * 前置、后置功能
 */

/**
 *
 * @param targetClassPrototype 【RoleService.prototype】 方法原型
 * @param key 方法名
 * @param methodDecri 数据访问属性
 */
// function MyMethodDecorator(targetClassPrototype: any,key: string, methodDecri: PropertyDescriptor) {
//   console.log("targetClassPrototype:", targetClassPrototype)//
//   console.log("key:", key);
//   console.log('数据属性:',methodDecri);
//   methodDecri.value();//! 执行被装饰器修饰的方法  分配角色.....

// }

//? 封装一个装饰器
function MethodInterceptor (paramsValue:any) {
  console.log("方法装饰器....");
  return function (targetClassPrototype:any, methodName:any, methodDecri:any) {
    //targetMethodSave.value 表示原来目标类HttpClient的show()方法
    // 1.1 先保存目标类的方法到targetMethodSave
    console.log("进入方法装饰器：methodDecri:", methodDecri);
    var targetMethodSave = methodDecri.value;
    console.log("targetMethodSave:", targetMethodSave);
    // 1.2.让value函数建立新得函数对象空间 
    //  value建立一个新的函数后,
    // RoleService对象调用DistribRoles;会执行value指向的新函数
    //  并不会执行原来RoleService目标类中DistribRoles方法
    //  这里建立的一个新函数就和后端 Java的spring AOP中的方法拦截器思想就完全一样
    methodDecri.value = function () {
      var args = [];
      for (var _i = 0; _i < arguments.length; _i++) {
        args[_i] = arguments[_i];
      }
      console.log("this: '不会执行'", this);
      // 迭代所有参数
      args = args.map(function (arg) {
        if (typeof arg === "string") {
          return 'string';
        }
        return arg;
      });
      console.log(args,'不会执行');
      // 1.4.总结:这是一种典型的用方法装饰器扩大原来方法功能的案例
      // 1.5 但如果增强原来方法功能后,还想继续执行原来RoleService类中DistribRoles方法
      // 使用apply执行targetMethodSave原来函数
      targetMethodSave.apply(this, args);
    };
    //  方法执行之后，继续执行后续代码
    console.log("后置拦截器");
  };
}
class RoleService {
  public roleName: string = "管理员";
  constructor() {}

  // @MyMethodDecorator // 不带参数的
  @MethodInterceptor('/user')
  DistribRoles() {
    // 分配角色
    console.log("分配角色.....");
  }
}

export {};
